package com.stockz.equity.scanner.screen;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.stockz.equity.indicator.ord.OrdIndicator;
import com.stockz.equity.indicator.ord.OrdSwing;
import com.stockz.equity.indicator.ord.OrdSwing.OrdSwingDirection;
import com.stockz.equity.model.Bar;
import com.stockz.equity.scanner.screen.configuration.OrdScreenConfiguration;

@Component
public class OrdScreen implements IndicatingScreen<OrdScreenConfiguration> {

	@Autowired
	private OrdIndicator ordIndicator;
	
	private final OrdScreenConfiguration configuration = new OrdScreenConfiguration();
	
	private double percentage = 5;
	private int mandatorySpan = 100;
	
	@Override
	public OrdScreenConfiguration getConfiguration() {
		return configuration;
	}
	
	@Override
	public int getMandatorySpan() {
		return mandatorySpan;
	}

	/*A buy signal is triggered when a stock closes above a
	previous low and Ord - Volume on the down leg declines by 50 percent or
	more compared with the previous up leg or previous down leg. Both conditions
	indicate the stock is in a strong position.*/
	
	@Override
	public boolean isMatch(List<Bar> barList) {
		
		if(barList == null || barList.size() <= mandatorySpan){
			return false;
		}
		ordIndicator.getIndicatorConfiguration().setPercentage(percentage);
		List<OrdSwing> ordSwingList = ordIndicator.getOrdSwingList(barList);
		return isOrdMatch(ordSwingList);
	}
	
	public boolean isOrdMatch(List<OrdSwing> ordSwingList){
		if(ordSwingList == null
				|| ordSwingList.size() <= 3 ){
			return false;
		}
		/*if(OrdSwingDirection.DOWN.equals(ordSwingList.get(0).getDirection())
				//&& ordSwingList.get(0).getEnd().getClose() > ordSwingList.get(1).getStart().getAveragePrice()
				&& (2*ordSwingList.get(0).getAverageDailyVolume() < ordSwingList.get(1).getAverageDailyVolume()
						|| 2*ordSwingList.get(0).getAverageDailyVolume() < ordSwingList.get(2).getAverageDailyVolume())){
			return true;
		}*/
		
		if(OrdSwingDirection.UP.equals(ordSwingList.get(0).getDirection())
				&& ordSwingList.get(0).getEnd().getClose() > ordSwingList.get(1).getStart().getAveragePrice()){
			
			return true;
		}
		
		return false;
	}
	
	@Override
	public List<Integer> getMatchingIndices(List<Bar> barList) {
		List<Integer> matchList = new ArrayList<Integer>();
		if(barList == null || barList.size() <= mandatorySpan){
			return matchList;
		}
		ordIndicator.getIndicatorConfiguration().setPercentage(percentage);
		List<OrdSwing> ordSwingList = ordIndicator.getOrdSwingList(barList);
		
		if(ordSwingList == null
				|| ordSwingList.size() <= 3 ){
			return matchList;
		}
		
		List<OrdSwing> subList = null;
		for(int i = 0; i < barList.size(); i++){
			Bar bar = barList.get(i);

			for(int j = 0; j < ordSwingList.size(); j++){
				OrdSwing ordSwing = ordSwingList.get(j);
				
				if(bar.equals(ordSwing.getEnd())){
					subList = ordSwingList.subList(j,ordSwingList.size());
					break;
				}else if(bar.getDate().after(ordSwing.getStart().getDate())
						&& bar.getDate().before(ordSwing.getEnd().getDate())){
					subList = ordSwingList.subList(j,ordSwingList.size());
					
					double volume = ordSwing.getVolume();
					double span = ordSwing.getSpan();
					Bar end = ordSwing.getEnd();
					
					ordSwing.setEnd(bar);
					ordSwing.setVolume(ordIndicator.getVolume(barList, ordSwing.getStart(), ordSwing.getEnd()));
					ordSwing.setSpan(ordIndicator.getSpan(barList, ordSwing.getStart(), ordSwing.getEnd()));
					if(isOrdMatch(subList)){
						matchList.add(i);
					}
					ordSwing.setVolume(volume);
					ordSwing.setSpan(span);
					ordSwing.setEnd(end);
					break;
				}
			}
			
			if(isOrdMatch(subList)){
				matchList.add(i);
			}
			
			
		}
		return matchList;
	}

	public double getPercentage() {
		return percentage;
	}

	public void setPercentage(double percentage) {
		this.percentage = percentage;
	}

}
